#include "tcp_server.h"
#include <iostream>
#include <cstring>
#include "logger.h"

TcpConnection::TcpConnection(int sock_fd, MessageHandler handler)
    : sock_fd_(sock_fd), connected_(true), message_handler_(handler) {}

TcpConnection::~TcpConnection() {
    connected_ = false;
    if (read_thread_.joinable()) {
        read_thread_.join();
    }
    if (sock_fd_ >= 0) {
        close(sock_fd_);
    }
}

void TcpConnection::start() {
    read_thread_ = std::thread(&TcpConnection::handle_read, this);
}

void TcpConnection::send(const std::string& message) {
    std::lock_guard<std::mutex> lock(write_mutex_);
    if (!connected_) return;
    
    // 添加换行符作为消息分隔符
    std::string framed_message = message + "\n";
    
    size_t total_sent = 0;
    while (total_sent < framed_message.length()) {
        ssize_t sent = write(sock_fd_, framed_message.c_str() + total_sent, 
                           framed_message.length() - total_sent);
        if (sent <= 0) {
            connected_ = false;
            return;
        }
        total_sent += sent;
    }
}

void TcpConnection::handle_read() {
    char buffer[BUFFER_SIZE];
    std::string message_buffer;  // 用于存储未完成的消息
    
    std::cout << "开始读取消息循环..." << std::endl;
    while (connected_) {
        std::cout << "等待读取数据..." << std::endl;
        ssize_t bytes_read = read(sock_fd_, buffer, BUFFER_SIZE - 1);
        std::cout << "读取到 " << bytes_read << " 字节数据" << std::endl;
        
        if (bytes_read <= 0) {
            std::cout << "读取错误或连接关闭: " << strerror(errno) << std::endl;
            connected_ = false;
            break;
        }
        
        buffer[bytes_read] = '\0';
        message_buffer += std::string(buffer, bytes_read);
        
        // 处理所有完整的消息
        while (true) {
            size_t end = message_buffer.find('\n');
            
            if (end == std::string::npos) {
                break;  // 没有找到完整的消息
            }
            
            // 提取消息内容（不包含换行符）
            std::string complete_message = message_buffer.substr(0, end);
            
            // 更新缓冲区，移除已处理的消息（包括换行符）
            message_buffer = message_buffer.substr(end + 1);
            
            // 处理消息
            if (message_handler_) {
                message_handler_(complete_message, this);
            }
        }
    }
}

TcpServer::TcpServer(int port) 
    : server_fd_(-1), port_(port), running_(false) {}

TcpServer::~TcpServer() {
    stop();
}

void TcpServer::start() {
    server_fd_ = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd_ < 0) {
        throw std::runtime_error("创建socket失败");
    }
    
    int opt = 1;
    if (setsockopt(server_fd_, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, 
                   &opt, sizeof(opt))) {
        throw std::runtime_error("设置socket选项失败");
    }
    
    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port_);
    
    if (bind(server_fd_, (struct sockaddr*)&address, sizeof(address)) < 0) {
        throw std::runtime_error("绑定端口失败");
    }
    
    if (listen(server_fd_, 10) < 0) {
        throw std::runtime_error("监听失败");
    }
    
    running_ = true;
    accept_thread_ = std::thread(&TcpServer::accept_connections, this);
}

void TcpServer::stop() {
    Logger::info("开始停止TCP服务器...");
    Logger::info("等待5秒钟...");
    sleep(5);
    running_ = false;
    
    // 1. 关闭监听socket，这会导致accept线程退出
    if (server_fd_ >= 0) {
        close(server_fd_);
        server_fd_ = -1;
    }
    
    // 2. 等待accept线程结束
    if (accept_thread_.joinable()) {
        Logger::info("等待接受连接线程结束...");
        accept_thread_.join();
    }
    
    // 3. 清理所有连接
    {
        std::lock_guard<std::mutex> lock(connections_mutex_);
        Logger::info("开始清理所有客户端连接...");
        for (auto conn : connections_) {
            delete conn;  // 这会触发TcpConnection析构函数，等待读取线程结束
        }
        connections_.clear();
    }
    
    Logger::info("TCP服务器停止完成");
}

void TcpServer::set_message_handler(TcpConnection::MessageHandler handler) {
    message_handler_ = handler;
}

void TcpServer::broadcast(const std::string& message) {
    std::lock_guard<std::mutex> lock(connections_mutex_);
    
    for (auto conn : connections_) {
        if (conn->is_connected()) {
            conn->send(message);
        }
    }
}

void TcpServer::accept_connections() {
    while (running_) {
        struct sockaddr_in client_addr;
        socklen_t addr_len = sizeof(client_addr);
        
        int client_fd = accept(server_fd_, (struct sockaddr*)&client_addr, &addr_len);
        if (client_fd < 0) {
            if (running_) {
                std::cerr << "接受连接失败: " << strerror(errno) << std::endl;
            }
            continue;
        }
        
        std::cout << "新的连接: " << inet_ntoa(client_addr.sin_addr) 
                  << ":" << ntohs(client_addr.sin_port) << std::endl;
        
        auto conn = new TcpConnection(client_fd, message_handler_);
        conn->start();
        {
            std::lock_guard<std::mutex> lock(connections_mutex_);
            connections_.insert(conn);
        }
    }
}